nodeを使って2501サーバの簡易模倣


概要

ビューを持ち出すわけにいかなかったので、でっち上げる。

写真もダメだったすまん。



構成

2501Slave Client x N

Unity + WS


WebSocket経由でlua scriptを実行することができる。

デバッグ中のみ必要で、リリースビルドに含むと審査に落ちる。

2501(PuppetMaster) + Slaveyard Server

node


Clientの操作コンテキスト管理と、群体制御、結果/モニタリング機能を受け持つ。


ブラウザ

2501の挙動はブラウザから見れる。

また、ブラウザから群体/個体に対してluaその他で制御コードやbotを送り込むことができる。



できること

・群体制御/個体制御

・スクショ好きな時に/自動化

・スクリプト実行(履歴はGUIに持たせてもいいしサーバに持たせてもいいし

・Tail

・エラープルーフ(スクリプト実行エラーがでてもまあ端末は死なない

・ボット常駐

・現在のゲームのコンテキストに則ったメソッド実行

・実行可能メソッド抽出

・メソッド待ち構え処理



群体制御/個体制御

接続してる全端末に向けて処理を並列でぶっとばせる。

・自動的に適当な画面まで進む、とかができる。

・ある端末をリーダーにしてその端末と同じ処理を他の端末に流して同期とかできる。


スクショ好きな時に/自動化

低負荷かつ異様に高速なスクリーンショット。

ファイル吐き出し or DB

(ReactのUIに表示したかったがまにあわんかった)

SCREENSHOTボタン押す



スクリプト実行(履歴はGUIに持たせてもいいしサーバに持たせてもいいし

luaから端末内の制御メソッドを叩ける。


scriptは端末側の都合のいいタイミングで実行されるので、端末ごとの入力ズレはほぼない。

ちなみに全てのスクリプトは、coroutineとかを書かない限り同一のフレームで同期的に実行される。


coroutineとか書くとフレームをまたいで実行できる。

つまり適当なスパンで端末のメソッドを叩ける。


backbone.Screenshot()



Tail

端末全部に対してTailを仕掛けられる。

実際にはもっと頻度は低いので、負荷は低い。(頻度は指定できる


TAILボタン押して端末動かす

Titleで放置したり、遷移先でAとかボタン押したり。


エラープルーフ(スクリプト実行エラーがでてもまあ端末は死なない

まあはい。ゲームの邪魔はしない。



ボット常駐

定期イベントでなんかするbotとかを書ける。luaだし。

こないだMackerelのイベント行った時に面白かったんでパクった。



現在のゲームのコンテキストに則ったメソッド実行

ゲーム内のインスタンスをluaから実行できる。

例えば TitleScript型のインスタンスと、そのメソッド があったら、TitleScript.メソッド(引数) という記法でluaから実行できる。

引数があるメソッドもぶったたける。

これによって、uGUIとかUnityで主流なGUIのメソッドは、ほぼすべて裏側から叩ける。



実行可能メソッド抽出

現在のUnityのコンテキストで実行可能なインスタンス一覧と、

そのインスタンスが保有している実行可能な関数一覧を取得する。


(UIがアレなんだけどまあプレゼン。)

availables ボタン ->

backbone.ReturnAllAvailables("CameraScript")


この返り値が、このCameraScriptインスタンスで、現在実行可能なメソッド集。

availables.targetInstanceName:CameraScript methodSignatures:

Awake(),

BackToTitle(),

ButtonTapped(System.String key),

Invoke(System.String methodName, System.Single time),

InvokeRepeating(System.String methodName, System.Single time, System.Single repeatRate),

CancelInvoke(),

CancelInvoke(System.String methodName),

IsInvoking(System.String methodName),

IsInvoking(),

StartCoroutine(System.String methodName, System.Object value),

StartCoroutine(System.String methodName),

StopCoroutine(System.String methodName),

StopAllCoroutines(),

GetComponent(System.String type),

CompareTag(System.String tag),

SendMessageUpwards(System.String methodName, System.Object value),

SendMessageUpwards(System.String methodName),

SendMessage(System.String methodName, System.Object value),

SendMessage(System.String methodName),

BroadcastMessage(System.String methodName, System.Object parameter),

BroadcastMessage(System.String methodName),

ToString(),

GetInstanceID(),

GetHashCode(),

Equals(System.Object o),

GetType()

わんさか返してくる。で、これは全部実行できる。


試しにTailした上で、ButtonTapped(string)を実行してみよう。

CameraScript.ButtonTapped("hello, devices.")


Tail結果にログが出たはず。



メソッド待ち構え処理

特定のメソッドの実行まで潜伏、メソッドの実行をトリガーにluaを実行することができる。


(UIがないけどまあできる。)



インスタンスを沈める

Backbone.Regist 関数を使って、任意のinstanceをゲーム中に2501に登録、そのインスタンスのメソッドを

ある程度自由に実行できる。


具体的には、publicで引数が string/number/bool ほか なメソッドを、luaからナチュラルにぶったたける。


前提として、適度にUIのインスタンスを

Backbone.Register(this);// thisは、たとえば Title クラスのインスタンス。

とかで沈める。Awakeとかで沈めとくといいと思う。

ここを自動化するのは安全性の面から考えてない。


これで、uGUIのボタンの動作とかを、luaから

Title.GoToGame()

みたいな感じでぶったたける。


luaで実行できる利点

・クライアント内にluaコンテキストを持てる

状態保持でき、それがC#側に波及しない。サンドボックスからの制御になるので状態を捨てやすい。

・coroutineを使って、適当なフレーム遅延を引き起こした上でGUIが裏から叩ける

coroutine最高という気持ち







今回のGUI作成のよもやまばなし

超ひさしぶりにnode触る。


満たしてて欲しい要件は、

サーバ:

・ws接続とhttp接続を受ける(wsのためのhttp getとかはws側のライブラリで処理できるととても良い

・binary受け取れる

・メモリ上に画像バイナリガンガン格納する -> 適当なフォルダに吐く

・モニタはそれを取得、表示する

クライアント

・luaが動く(execute用途、bot用途


とかか。

React + node + Webpack + Material UIでやろう(死亡フラグ



ws使う

あ、FileServerみたいなのがある、、、まじか、、

開いて読むとこまではつかえたんだけどこれアップローダだな、要らね、、


とりあえず接続可能になるとこまでやろう。

-> 32ビット以上のサイズを受け付けられない。ああ、、


-> 単にリミットしてあった。スクリーンショットのサイズは必ず64bitあたりになるんで、まあ、はい。

解除してしまったところ動いた。

OK。



今回のGUI

適当にReactで作ってみた。めっちゃ勉強になった。



ちょっと試してみたい:http/2

node.js http/2



ちょっと試してみたい、grpc。

https://github.com/google/dorusu-js

https://github.com/grpc/grpc/tree/master/examples/node